#include <common/moneyconverter/moneyconverter.h>
#include <common/stringverify/stringverify.h>
#include <common/stringutil/stringutil.h>
#include <cctype>
#include <sstream>

std::string MoneyConverter::cvtNumber2RMB(const std::string& money)
{
	if (!StringVerify::isNumber(money))
	{
		return "非法金额";
	}
	// 去除空格
	std::string moneyTrim = StringUtil::trimEdge(money);
	if (moneyTrim.empty())
	{
		return "";
	}

	double moneyDouble;
	try
	{
		moneyDouble = std::stod(moneyTrim);
	}
	catch (...)
	{
		return "输入无效";
	}

	// 取绝对值
	moneyDouble = fabs(moneyDouble);

	if (moneyDouble > 1e13)
	{
		return "溢出";
	}
	if (moneyDouble == 0.0)
	{
		return "零元整";
	}

	// 中文数字和单位
	const std::string numberChars[] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
	const std::string unitChars[] = {"", "拾", "佰", "仟"};
	const std::string bigUnits[] = {"", "万", "亿", "万亿"};

	// 转换为分
	long long totalFen = static_cast<long long>(moneyDouble * 100 + 0.5);
	long long integerPart = totalFen / 100;
	// 单独处理角和分
	int jiao = (totalFen / 10) % 10;
	int fen = totalFen % 10;

	std::ostringstream oss;

	// 整数部分
	if (integerPart > 0)
	{
		std::string integerStr = std::to_string(integerPart);
		int len = integerStr.length();
		bool zeroFlag = false;// 记录零是否要写
		bool writeBigUnits = false;
		for (int i = 0; i < len; i++)
		{
			int num = integerStr[i] - '0';
			int pos = len - i - 1;// 当前位置
			int unitPos = pos % 4;// 拾、佰、仟
			int bigPos = pos / 4; // 万、亿、万亿

			if (num == 0)
			{
				zeroFlag = true;
			}
			else
			{
				writeBigUnits = true;
				if (zeroFlag)
				{
					oss << numberChars[0];
					zeroFlag = false;
				}
				oss << numberChars[num] << unitChars[unitPos];
			}
			// 判断是否要写入万，亿，万亿这些大单位
			if (writeBigUnits && unitPos == 0)
			{
				writeBigUnits = false;
				oss << bigUnits[bigPos];
			}
		}
		oss << "元";
	}

	// 小数部分
	if (jiao == 0 && fen == 0)
	{
		oss << "整";
	}
	else
	{
		if (jiao != 0)
		{
			oss << numberChars[jiao] << "角";
		}
		else if (integerPart != 0)
		{
			// 元和分之间要补零
			oss << "零";
		}
		if (fen != 0)
		{
			oss << numberChars[fen] << "分";
		}
	}

	return oss.str();
}
std::string MoneyConverter::cvtNumber2RMB(double money)
{
	return cvtNumber2RMB(std::to_string(money));
}
